package com.example.demo.security;


import org.apache.commons.codec.binary.Base64;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class SecurityTest {
    public static void main(String[] args) throws Exception {
        String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDBnNeBB3+U8WFAn0ONMYOdsVnogDkjEqoq46JLuNx7lKPJqKCQ9nOViMlavYQ8N0k9vMz1NIt00hZu7DByySzwWO65EmiAOSGYsOB+71bZ+SvvFuFp6Wuc2S3LV+eHHB3jpvQftf8tEI5lr9WBvVTtOKqC8ekq/1fTQZ/b/+TYvuqYFdM2kFWR7ugVMJ/CVrXcOCwjivALS3mIIkC30Pmye2n/H/oaRdJTSUwa1kmFa4Kmlhkc38sd8EhKTAeDOF9ePY4Nb6T0Q0BV46YVuqpoVpbc7VuQVwFX425PiE01IWMNAxnW79U1O4iQycbndnvPrWq5FbGaRWiibjkPtQSnAgMBAAECggEBAICW8c6hs0uyEXyBCrWRCDBI5UT1PH2d3OVFcLpIGi/95dZ+p73/4X6Ubd9VdakkswFNDvdgoarCCeI7/mWOVcl/13WV01AuIbEu8Lt9rLpysopGMQpN3Io8+BxQ0tY6h2N2tDcHgmZk056X7P8RR4GSnDUCBHHpS2Rk9o6AY3bMFceR7Dr9z/goluwm/vJBPvj2kKPQBOMizMyaeT90i5fqHj1j9i1fBs+mohzu/CpjSTm0OglHB2UocSP4Ojx7VQGsOpYFpDHZ7e8qxTg7zmTQY/h+ZblBDnnHAYpGax5jF2yz/JW3Xbx78uAvkCXOFwwlw61pVT7QsfNOuprdFXECgYEA7nfxsC1fajdJszReGKBAc91+DecSd4cuKHvEV5giA4uO1uMjnc90ojC28D00oZECgBn8gSKwMZfdOUtuuu/W2K19axol8FjidhIpmHLcEYmBvEK07Na3FI6GmndHTOxkACkhp3TQftcKwKbG/CBcwtyG7U1PbHtvnzFvYxUyR/kCgYEAz9iyEXHzUVZ9YhELZQT/EmtJ67x5vK5AMZeYhQ1SqhFFPeiEMzVrXLZN3Ykh+dzmSURutT1+DD7Pdjk9ur33As/GCLfBRfIEMEhqfkJeA57Fvu/dAroUMLA6gHNbzmYxUNjiyTxbshJbh97keLNWad9149O3bugvd8uxy7rLGZ8CgYEAz0GB1ivpFIiOzmiCK4cD3W+wweaFv0rGzDqdb7/yOACQGaV57AtFBD2wkWWwm4dLlAiB075RQhkKFWTBDUmsAc/vBCnKtXSbBiFM84lISRmonvWfB4Spw/0HcbKfTnTZiOY2sLKvDr5ZQwzwPmrmFBnUTuR1VgSGA+bUN1pRxAkCgYAQhE/iQwPq+syL9n7JUFRUymHdceTasZ44Uqu0JxLioOy3trqKtzwI6hPV/wfMK1nBiMajcHeL0ZH6+yGErYPrnUdHehLJ1CmxDJAp6GxALWXZfoY5qT/hfp+nhYNOK6DPo+yhwUIoLH1JltThIp9DWparvC9fiOP8yRsf7YAmUQKBgDrQHxnwL5A4uRV4mEqy3CT7hnS2GMVDHKHeVxHrvuBPTZM8pPsP+ERBLakX+dRl9zHlsSXyf+d1ky3ubYNVPXdMBgpWQBp+eTXSokDUxHaZ1oofnG11vY+YXqPklp0cgr6pohtoi2nuNvH5LzdCK5ut43jctwGJN793ywVOHguT";
        String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwZzXgQd/lPFhQJ9DjTGDnbFZ6IA5IxKqKuOiS7jce5SjyaigkPZzlYjJWr2EPDdJPbzM9TSLdNIWbuwwcsks8FjuuRJogDkhmLDgfu9W2fkr7xbhaelrnNkty1fnhxwd46b0H7X/LRCOZa/Vgb1U7TiqgvHpKv9X00Gf2//k2L7qmBXTNpBVke7oFTCfwla13DgsI4rwC0t5iCJAt9D5sntp/x/6GkXSU0lMGtZJhWuCppYZHN/LHfBISkwHgzhfXj2ODW+k9ENAVeOmFbqqaFaW3O1bkFcBV+NuT4hNNSFjDQMZ1u/VNTuIkMnG53Z7z61quRWxmkVoom45D7UEpwIDAQAB";
        String data = "wang@fei";
        String signStr = sha256WithRsaSign(data, privateKey);
        System.out.println("The Sign: " + signStr);
        System.out.println("The result verified: " + sha256WithRsaSignVerify(signStr, data, publicKey));
    }

    /**
     * SHA256WithRSA签名算法，jdk低于1.7可以能会报错No installed provider supports this key，
     * 需要另外添加provider，例如：Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())
     * @param data 要签名的数据
     * @param privateKey 私钥
     * @return 返回签名字符串，经过base64编码
     * @throws Exception
     */
    private static String sha256WithRsaSign(String data, String privateKey) throws Exception{
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey1 = factory.generatePrivate(pkcs8EncodedKeySpec);
        Signature signature = Signature.getInstance("SHA256WithRSA");
        signature.initSign(privateKey1);
        signature.update(data.getBytes("UTF-8"));
        return Base64.encodeBase64String(signature.sign());
    }

    /**
     * SHA256WithRSA签名算法，jdk低于1.7可以能会报错No installed provider supports this key，
     * 需要另外添加provider，例如：Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())
     * @param signStr 签名串
     * @param data 要检验的内容
     * @param publicKey 公钥
     * @return 返回是否成功：true成功，false失败
     * @throws Exception
     */
    private static boolean sha256WithRsaSignVerify(String signStr, String data, String publicKey) throws Exception{
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey1 = keyFactory.generatePublic(x509EncodedKeySpec);
        Signature signature = Signature.getInstance("SHA256WithRSA");
        signature.initVerify(publicKey1);
        signature.update(data.getBytes("UTF-8"));
        return signature.verify(Base64.decodeBase64(signStr));
    }
}
